unit Editor;

interface

uses
  Color,
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ComCtrls, StdCtrls, ExtCtrls, Menus, Buttons, Printers;

type
  TFormEditor = class(TForm)
    Status: TStatusBar;
    MainMenu: TMainMenu;
    MenuFile: TMenuItem;
    MenuAutotype: TMenuItem;
    Autotype2: TMenuItem;
    MenuSave: TMenuItem;
    MenuSaveAs: TMenuItem;
    MenuOpen: TMenuItem;
    MenuExit: TMenuItem;
    MenuNew: TMenuItem;
    DialogOpen: TOpenDialog;
    DialogSave: TSaveDialog;
    N4: TMenuItem;
    MenuSelectAll: TMenuItem;
    N5: TMenuItem;
    MenuPrint: TMenuItem;
    DialogPrint: TPrintDialog;
    N1: TMenuItem;
    MenuIncreaseFont: TMenuItem;
    MenuDecreaseFont: TMenuItem;
    PanelToolbar: TPanel;
    BtnNew: TSpeedButton;
    BtnOpen: TSpeedButton;
    BtnAutotype: TSpeedButton;
    BtnSave: TSpeedButton;
    BtnPrint: TSpeedButton;
    BtnCut: TSpeedButton;
    BtnCopy: TSpeedButton;
    BtnPaste: TSpeedButton;
    BtnFontDown: TSpeedButton;
    BtnFontUp: TSpeedButton;
    MenuCut: TMenuItem;
    MenuCopy: TMenuItem;
    MenuPaste: TMenuItem;
    N2: TMenuItem;
    Spacer: TShape;
    DialogFont: TFontDialog;
    BtnFont: TSpeedButton;
    MenuFont: TMenuItem;
    MenuLast1: TMenuItem;
    MenuLast2: TMenuItem;
    MenuLast3: TMenuItem;
    MenuLast4: TMenuItem;
    MenuReopen: TMenuItem;
    MenuLast5: TMenuItem;
    MenuLast6: TMenuItem;
    MenuLast7: TMenuItem;
    MenuLast8: TMenuItem;
    MenuLast9: TMenuItem;
    MenuLast0: TMenuItem;
    MenuBar: TMenuItem;
    MenuClearAll: TMenuItem;
    MenuNone: TMenuItem;
    MenuNewTemplate: TMenuItem;
    MenuNote: TMenuItem;
    MenuMailSingleRecipient: TMenuItem;
    MenuMailMultipleRecipient: TMenuItem;
    N3: TMenuItem;
    DialogReplace: TReplaceDialog;
    MenuSearch: TMenuItem;
    MenuFind: TMenuItem;
    MenuFindNext: TMenuItem;
    BtnFind: TSpeedButton;
    BtnFindNext: TSpeedButton;
    PanelEditor: TPanel;
    MenuOptions: TMenuItem;
    MenuShowWidthbar: TMenuItem;
    Escape: TMenuItem;
    BtnSelectAll: TSpeedButton;
    N6: TMenuItem;
    BtnUndo: TSpeedButton;
    N7: TMenuItem;
    MenuUndo: TMenuItem;
    BtnHelp: TSpeedButton;
    MenuHelp: TMenuItem;
    MenuAutotyperHelp: TMenuItem;
    LabelFont: TLabel;
    Bevel1: TBevel;
    Popup: TPopupMenu;
    PopupCut: TMenuItem;
    PopupCopy: TMenuItem;
    PopupPaste: TMenuItem;
    PopupAutotype: TMenuItem;
    N8: TMenuItem;
    PopupUndo: TMenuItem;
    PopupSelectAll: TMenuItem;
    PopupPrint: TMenuItem;
    N9: TMenuItem;
    MenuDeleteLine: TMenuItem;
    BtnClear: TSpeedButton;
    MenuDeleteAll: TMenuItem;
    MenuSaveAlert: TMenuItem;
    MenuClearOnAutotype: TMenuItem;
    MenuAskOnEmpty: TMenuItem;
    MenuEnableWordWrap: TMenuItem;
    MenuCtrlTab: TMenuItem;
    MenuCtrlTab2: TMenuItem;
    MenuInvisible: TMenuItem;
    MenuChat: TMenuItem;
    MenuTell: TMenuItem;
    MenuStatus: TMenuItem;
    MenuMessage: TMenuItem;
    MenuImagery: TMenuItem;
    MenuFToolbar: TMenuItem;
    MenuExit2: TMenuItem;
    MenuPanic: TMenuItem;
    MenuStayOnTop: TMenuItem;
    MenuFindNext2: TMenuItem;
    BtnDeleteLine: TSpeedButton;
    MenuFiltered: TMenuItem;
    MenuChooseColors: TMenuItem;
    N10: TMenuItem;
    BtnColors: TSpeedButton;
    MenuVariables: TMenuItem;
    MenuMap: TMenuItem;
    Data1: TMenuItem;
    Tabs: TPageControl;
    Tab1: TTabSheet;
    PanelWidth1: TPanel;
    EditWidth1: TEdit;
    Editor1: TMemo;
    Tab2: TTabSheet;
    Tab3: TTabSheet;
    PanelWidth2: TPanel;
    EditWidth2: TEdit;
    Editor2: TMemo;
    PanelWidth3: TPanel;
    EditWidth3: TEdit;
    Editor3: TMemo;
    BtnSaveAll: TSpeedButton;
    MenuSaveAll: TMenuItem;
    MenuFile1: TMenuItem;
    MenuFile2: TMenuItem;
    MenuFile3: TMenuItem;
    Tab4: TTabSheet;
    PanelWidth4: TPanel;
    EditWidth4: TEdit;
    Editor4: TMemo;
    MenuFile4: TMenuItem;
    Canvas1: TMenuItem;
    BtnSpellCheck: TSpeedButton;
    BtnThesarus: TSpeedButton;
    N11: TMenuItem;
    CheckSpelling1: TMenuItem;
    MenuThesaurus: TMenuItem;
    MenuDownload: TMenuItem;
    N12: TMenuItem;
    procedure MenuExitClick(Sender: TObject);
    procedure MenuAutotypeClick(Sender: TObject);
    procedure MenuSaveAsClick(Sender: TObject);
    procedure MenuOpenClick(Sender: TObject);
    procedure Editor1Change(Sender: TObject);
    procedure MenuSaveClick(Sender: TObject);
    procedure MenuNewClick(Sender: TObject);
    procedure MenuSelectAllClick(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure MenuPrintClick(Sender: TObject);
    procedure MenuIncreaseFontClick(Sender: TObject);
    procedure MenuDecreaseFontClick(Sender: TObject);
    procedure FormResize(Sender: TObject);
    procedure MenuCutClick(Sender: TObject);
    procedure MenuCopyClick(Sender: TObject);
    procedure MenuPasteClick(Sender: TObject);
    procedure MenuFontClick(Sender: TObject);
    procedure BtnAutotypeMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure FormShow(Sender: TObject);
    procedure MenuClearAllClick(Sender: TObject);
    procedure MenuLast0Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure MenuNoteClick(Sender: TObject);
    procedure MenuFindClick(Sender: TObject);
    procedure MenuFindNextClick(Sender: TObject);
    procedure DialogReplaceReplace(Sender: TObject);
    procedure DialogReplaceFind(Sender: TObject);
    procedure MenuShowWidthbarClick(Sender: TObject);
    procedure MenuUndoClick(Sender: TObject);
    procedure BtnHelpClick(Sender: TObject);
    procedure FormKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure Editor1MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure MenuDeleteLineClick(Sender: TObject);
    procedure EditWidth1Click(Sender: TObject);
    procedure EscapeClick(Sender: TObject);
    procedure MenuDeleteAllClick(Sender: TObject);
    procedure MenuCtrlTabClick(Sender: TObject);
    procedure MenuChatClick(Sender: TObject);
    procedure MenuPanicClick(Sender: TObject);
    procedure MenuStayOnTopClick(Sender: TObject);
    procedure MenuChooseColorsClick(Sender: TObject);
    procedure TabsChange(Sender: TObject);
    procedure MenuSaveAllClick(Sender: TObject);
    procedure MenuFile1Click(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure BtnSpellCheckClick(Sender: TObject);
    procedure MenuDownloadClick(
      Sender: TObject);
  private
    { Private declarations }
    FStr, FPtr, FTarget, RStr: PChar;
    procedure WMGetMinMaxInfo(var MSG: Tmessage); message WM_GetMinMaxInfo;
    procedure PrepareSearch(Sender: TObject);
    function DoSearch: boolean;
    procedure DoReplace;
    procedure LoadFiles;
    procedure SaveFiles;
    procedure UpdateMenu;
    procedure FilterMenu;
    procedure AddFile(str: string);
    procedure UpdateCursorPos;
    function ActiveFile: string;
    procedure UpdateCaption;
    procedure UpdateCaptions;
    procedure SetActiveSaved(str: string);
    procedure SetActiveChanged;
    procedure UpdateSaves;
    procedure CheckContent;
  public
    { Public declarations }
    LastFiles: TStringList;
    procedure UpdateFontSize;
    function ActiveEditor: TMemo;
    procedure FocusFile(which: integer);
  end;

var
  FormEditor: TFormEditor;
  currentline: integer;
  file1, file2, file3, file4: string;
  m1, m2, m3, m4: boolean;

implementation

uses Database, Main;

{$R *.DFM}

procedure TFormEditor.FormCreate(Sender: TObject);
begin
  LastFiles:=TStringList.create;
end;

procedure TFormEditor.FormShow(Sender: TObject);
begin
  LoadFiles;
  if FormMain.panicking then exit;
  Editor1.lines.clear;
  Editor2.lines.clear;
  Editor3.lines.clear;
  Editor4.lines.clear;
  file1:='untitled';
  file2:='untitled';
  file3:='untitled';
  file4:='untitled';
  m1:=false;
  m2:=false;
  m3:=false;
  m4:=false;
  currentline:=0;
  UpdateCaptions;
  UpdateCaption;
  Tabs.activepage:=tab1;
  TabsChange(sender);
end;

procedure TFormEditor.WMGetMinMaxInfo(var MSG: Tmessage);
begin
  inherited;
  with PMinMaxInfo(MSG.lparam)^ do begin
    with ptMinTrackSize do begin
      X := 300;
      Y := 200;
    end;
    with ptMaxTrackSize do begin
      X := 9999;
      Y := 9999;
    end;
  end;
end;

function TFormEditor.ActiveEditor: TMemo;
begin
  if Tabs.activepage = Tab1 then result:=Editor1
  else if Tabs.activepage = Tab2 then result:=Editor2
  else if Tabs.activepage = Tab3 then result:=Editor3
  else result:=Editor4;
end;

function TFormEditor.ActiveFile: string;
begin
  if Tabs.activepage = Tab1 then result:=file1
  else if Tabs.activepage = Tab2 then result:=file2
  else if Tabs.activepage = Tab3 then result:=file3
  else result:=file4;
end;

procedure TFormEditor.SetActiveSaved(str: string);
begin
  if Tabs.activepage = Tab1 then begin
    if str <> '' then file1:=str;
    m1:=false;
  end
  else if Tabs.activepage = Tab2 then begin
    if str <> '' then file2:=str;
    m2:=false;
  end
  else if Tabs.activepage = Tab3 then begin
    if str <> '' then file3:=str;
    m3:=false;
  end
  else begin
    if str <> '' then file4:=str;
    m4:=false;
  end;
  UpdateCaption;
  UpdateCaptions;
end;

procedure TFormEditor.SetActiveChanged;
begin
  if Tabs.activepage = Tab1 then m1:=true
  else if Tabs.activepage = Tab2 then m2:=true
  else if Tabs.activepage = Tab3 then m3:=true
  else m4:=true;
  UpdateCaptions;
end;

procedure TFormEditor.UpdateCaption;
var str: string;
begin
  if Tabs.activepage = Tab1 then str:=file1
  else if Tabs.activepage = Tab2 then str:=file2
  else if Tabs.activepage = Tab3 then str:=file3
  else str:=file4;
  caption:='Autotyper - '+str;
end;

procedure TFormEditor.UpdateCaptions;
var flag: string;
begin
  if m1 then flag:='*' else flag:='';
  Tab1.caption:=extractfilename(file1)+flag+'  [F9]';
  if m2 then flag:='*' else flag:='';
  Tab2.caption:=extractfilename(file2)+flag+'  [F10]';
  if m3 then flag:='*' else flag:='';
  Tab3.caption:=extractfilename(file3)+flag+'  [F11]';
  if m4 then flag:='*' else flag:='';
  Tab4.caption:=extractfilename(file4)+flag+'  [F12]';
end;

procedure TFormEditor.FormResize(Sender: TObject);
begin
  EditWidth1.width:=PanelWidth1.width-1;
  EditWidth2.width:=EditWidth1.width;
  EditWidth3.width:=EditWidth1.width;
  EditWidth4.width:=EditWidth1.width;
end;

procedure TFormEditor.PrepareSearch(Sender: TObject);
begin
  if assigned(FStr) then StrDispose(FStr);
  if assigned(FTarget) then StrDispose(FTarget);
  FStr:=StrAlloc(ActiveEditor.gettextlen+1);
  ActiveEditor.gettextbuf(Fstr,ActiveEditor.gettextlen+1);
  FPtr:=FStr;
  with (sender as TReplaceDialog) do begin
    FTarget:=StrAlloc(length(FindText)+1);
    StrPCopy(FTarget,FindText);
    if not (frMatchCase in Options) then begin
      StrUpper(FStr);
      StrUpper(FTarget);
    end;
  end;
end;

function TFormEditor.DoSearch: boolean;
begin
  while FPtr <> nil do begin
    FPtr:=StrScan(FPtr,FTarget[0]);
    if FPtr <> nil then begin
      if StrLComp(FPtr,FTarget,StrLen(FTarget)) = 0 then begin
        ActiveEditor.SetFocus;
        ActiveEditor.SelStart:=FPtr-FStr;
        ActiveEditor.SelLength:=StrLen(FTarget);
        FPtr:=FPtr+1;
        DoSearch:=true;
        exit;
      end;
    end
    else break;
    FPtr:=FPtr+1;
  end;
  DoSearch:=false;
end;

procedure TFormEditor.DoReplace;
var ofs: integer;
begin
  ActiveEditor.SetSelTextBuf(RStr);
  ofs:=FPtr-FStr-1;
  StrDispose(FStr);
  FStr:=StrAlloc(ActiveEditor.GetTextLen+1);
  ActiveEditor.GetTextBuf(FStr,ActiveEditor.GetTextLen+1);
  if not (frMatchCase in DialogReplace.Options) then StrUpper(FStr);
  FPtr:=FStr+ofs+StrLen(RStr);
end;

procedure TFormEditor.MenuExitClick(Sender: TObject);
begin
  close;
end;

procedure TFormEditor.MenuAutotypeClick(Sender: TObject);
var
  work: string;
  i: integer;
begin
  if (not Datawell.connected) and (not Datawell.connected2) then begin
    messagedlg('Not connected to server',mtinformation,[mbok],0);
    exit;
  end;
  if ActiveEditor.lines.count < 1 then begin
    messagedlg('Nothing to autotype',mtinformation,[mbok],0);
    exit;
  end;
  FormMain.show;
  for i:=0 to ActiveEditor.lines.count-1 do begin
    work:=ActiveEditor.lines[i];
    FormMain.ExternalParse(work,2);
  end;
  if MenuClearOnAutotype.checked then MenuDeleteAll.click;
end;

procedure TFormEditor.MenuSaveClick(Sender: TObject);
begin
  if ActiveFile = 'untitled' then begin
    MenuSaveAsClick(sender);
    exit;
  end;
  ActiveEditor.lines.savetofile(ActiveFile);
  AddFile(ActiveFile);
  SetActiveSaved('');
  UpdateSaves;
  UpdateCaptions;
end;

procedure TFormEditor.MenuSaveAllClick(Sender: TObject);
begin
  //File1
  if m1 then begin
    if file1 = 'untitled' then begin
      Tabs.activepage:=Tab1;
      TabsChange(sender);
      MenuSaveAsClick(sender);
    end
    else begin
      Editor1.lines.savetofile(file1);
      AddFile(ActiveFile);
      m1:=false;
    end;
  end;
  //File2
  if m2 then begin
    if file2 = 'untitled' then begin
      Tabs.activepage:=Tab2;
      TabsChange(sender);
      MenuSaveAsClick(sender);
    end
    else begin
      Editor2.lines.savetofile(file2);
      AddFile(ActiveFile);
      m2:=false;
    end;
  end;
  //File3
  if m3 then begin
    if file3 = 'untitled' then begin
      Tabs.activepage:=Tab3;
      TabsChange(sender);
      MenuSaveAsClick(sender);
    end
    else begin
      Editor3.lines.savetofile(file3);
      AddFile(ActiveFile);
      m3:=false;
    end;
  end;
  //File4
  if m4 then begin
    if file4 = 'untitled' then begin
      Tabs.activepage:=Tab4;
      TabsChange(sender);
      MenuSaveAsClick(sender);
    end
    else begin
      Editor4.lines.savetofile(file4);
      AddFile(ActiveFile);
      m4:=false;
    end;
  end;
  UpdateCaptions;
  UpdateCaption;
  UpdateSaves;
end;

procedure TFormEditor.MenuSaveAsClick(Sender: TObject);
var work: string;
begin
  if ((Tabs.activepage = Tab1) and (file1 = 'untitled')) or
    ((Tabs.activepage = Tab2) and (file2 = 'untitled')) or
    ((Tabs.activepage = Tab3) and (file3 = 'untitled')) or
    ((Tabs.activepage = Tab4) and (file4 = 'untitled')) then
    DialogSave.filename:='untitled';
  DialogSave.initialdir:=Datawell.GetDir(2);
  if DialogSave.execute = false then begin
    FormMain.loginclose:=false;
    abort;
  end;
  Datawell.SetDir(2,DialogSave.filename);
  work:=DialogSave.filename;
  while (length(work) > 0) and (work[length(work)] <> '\') do delete(work,length(work),1);
  if DialogSave.filterindex = 2 then begin
    if pos('.',DialogSave.filename) < 1 then
      DialogSave.filename:=DialogSave.filename+'.txt'
  end;
  ActiveEditor.lines.savetofile(DialogSave.filename);
  AddFile(DialogSave.filename);
  SetActiveSaved(DialogSave.filename);
  UpdateSaves;
end;

procedure TFormEditor.Editor1Change(Sender: TObject);
begin
  Datawell.idle:=0;
  SetActiveChanged;
  BtnSave.enabled:=true;
  BtnSaveAll.enabled:=true;
  Status.panels[1].text:='Modified';
  CheckContent;
  UpdateCursorPos;
end;

procedure TFormEditor.CheckContent;
begin
  if length(ActiveEditor.text) > 0 then begin
    MenuAutotype.enabled:=true;
    BtnAutotype.enabled:=true;
    FormMain.UpdateAutotyperButtons(true);
  end
  else begin
    MenuAutotype.enabled:=false;
    BtnAutotype.enabled:=false;
    FormMain.UpdateAutotyperButtons(false);
    if not MenuAskOnEmpty.checked then begin
      SetActiveSaved('');
      Status.panels[1].text:='';
      UpdateCaptions;
      UpdateSaves;
    end;
  end;
end;

procedure TFormEditor.MenuOpenClick(Sender: TObject);
var
  mr: TModalResult;
  notexiting: boolean;
  work: string;
begin
  if BtnSave.enabled then begin
    messagebeep($FFFFFFFF);
    mr:=messagedlg('Save changes to '+ActiveFile+'?',
      mtconfirmation,[mbyes,mbno,mbcancel],0);
    if mr = mrcancel then exit;
    if mr = mryes then MenuSaveClick(sender);
  end;
  DialogOpen.initialdir:=Datawell.GetDir(2);
  notexiting:=DialogOpen.execute;
  if not notexiting then exit;
  Datawell.SetDir(2,DialogOpen.filename);
  work:=DialogOpen.filename;
  while (length(work) > 0) and (work[length(work)] <> '\') do delete(work,length(work),1);
  try ActiveEditor.lines.loadfromfile(DialogOpen.filename);
    except on EFOpenError do begin
      messagedlg('The file is locked by another application',mtinformation,[mbok],0);
      exit;
    end;
  end;
  Status.panels[1].text:='';
  DialogSave.filename:=DialogOpen.filename;
  AddFile(DialogOpen.filename);
  SetActiveSaved(DialogOpen.filename);
  UpdateSaves;
end;

procedure TFormEditor.MenuNewClick(Sender: TObject);
var mr: TModalResult;
begin
  if BtnSave.enabled then begin
    messagebeep($FFFFFFFF);
    mr:=messagedlg('Save changes to '+DialogSave.filename+'?',
      mtconfirmation,[mbyes,mbno,mbcancel],0);
    if mr = mrcancel then abort;
    if mr = mryes then MenuSaveClick(sender)
  end;
  ActiveEditor.lines.clear;
  DialogOpen.filename:='untitled';
  DialogSave.filename:='untitled';
  Status.panels[0].text:='Line: 1 / 1';
  Status.panels[1].text:='';
  SetActiveSaved('untitled');
  UpdateSaves;
end;

procedure TFormEditor.MenuSelectAllClick(Sender: TObject);
begin
  ActiveEditor.selectall;
end;

procedure TFormEditor.FormClose(Sender: TObject; var Action: TCloseAction);
var mr: TModalResult;
begin
  if not visible then exit;
  if MenuSaveAlert.checked then begin
    if m1 then begin
      Tabs.activepage:=Tab1;
      TabsChange(sender);
      if (length(Editor1.text) < 1) and (not MenuAskOnEmpty.checked) then exit;
      messagebeep($FFFFFFFF);
      mr:=messagedlg('Save changes to '+file1+'?  [File 1]',
        mtconfirmation,[mbyes,mbno,mbcancel],0);
      if mr = mrcancel then begin
        FormMain.loginclose:=false;
        abort;
      end;
      if mr = mryes then MenuSaveClick(sender)
    end;
    if m2 then begin
      Tabs.activepage:=Tab2;
      TabsChange(sender);
      if (length(Editor2.text) < 1) and (not MenuAskOnEmpty.checked) then exit;
      messagebeep($FFFFFFFF);
      mr:=messagedlg('Save changes to '+file2+'?  [File 2]',
        mtconfirmation,[mbyes,mbno,mbcancel],0);
      if mr = mrcancel then begin
        FormMain.loginclose:=false;
        abort;
      end;
      if mr = mryes then MenuSaveClick(sender)
    end;
    if m3 then begin
      Tabs.activepage:=Tab3;
      TabsChange(sender);
      if (length(Editor3.text) < 1) and (not MenuAskOnEmpty.checked) then exit;
      messagebeep($FFFFFFFF);
      mr:=messagedlg('Save changes to '+file3+'?  [File 3]',
        mtconfirmation,[mbyes,mbno,mbcancel],0);
      if mr = mrcancel then begin
        FormMain.loginclose:=false;
        abort;
      end;
      if mr = mryes then MenuSaveClick(sender)
    end;
    if m4 then begin
      Tabs.activepage:=Tab4;
      TabsChange(sender);
      if (length(Editor4.text) < 1) and (not MenuAskOnEmpty.checked) then exit;
      messagebeep($FFFFFFFF);
      mr:=messagedlg('Save changes to '+file4+'?  [File 4]',
        mtconfirmation,[mbyes,mbno,mbcancel],0);
      if mr = mrcancel then begin
        FormMain.loginclose:=false;
        abort;
      end;
      if mr = mryes then MenuSaveClick(sender)
    end;
  end;
  MenuAutotype.enabled:=false;
  BtnAutotype.enabled:=false;
  FormMain.UpdateAutotyperButtons(false);
  SaveFiles;
  FormMain.UnloadScreen(11);
  action := caFree;
end;

procedure TFormEditor.MenuPrintClick(Sender: TObject);
var
  tab: string;
  PF: System.text;
  i: integer;
begin
  if ActiveEditor.lines.count < 1 then begin
    messagedlg('Nothing to print',mtinformation,[mbok],0);
    exit;
  end;
  if not DialogPrint.execute then exit;
  tab:='  ';
  AssignPRN(PF);
  ReWrite(PF);
  Printer.title:=Datawell.ptitle;
  Printer.canvas.font.assign(ActiveEditor.font);
  Printer.canvas.font.color:=clblack;
  if ActiveFile <> 'untitled' then writeln(PF,tab+ActiveFile);
  writeln(PF,'');
  for i:=0 to ActiveEditor.lines.count-1 do begin
    writeln(PF,tab+ActiveEditor.lines[i]);
  end;
  CloseFile(PF);
  ActiveEditor.setfocus;
end;

procedure TFormEditor.MenuDecreaseFontClick(Sender: TObject);
begin
  if Editor1.font.size <= 6 then exit;
  Editor1.font.size:=Editor1.font.size-1;
  Editor2.font.size:=Editor1.font.size;
  Editor3.font.size:=Editor1.font.size;
  Editor4.font.size:=Editor1.font.size;
  EditWidth1.font.assign(Editor1.font);
  EditWidth1.font.color:=clblack;
  EditWidth2.font.assign(Editor1.font);
  EditWidth2.font.color:=clblack;
  EditWidth3.font.assign(Editor1.font);
  EditWidth3.font.color:=clblack;
  EditWidth4.font.assign(Editor1.font);
  EditWidth4.font.color:=clblack;
  UpdateFontSize;
end;

procedure TFormEditor.MenuIncreaseFontClick(Sender: TObject);
begin
  if Editor1.font.size >= 20 then exit;
  Editor1.font.size:=Editor1.font.size+1;
  Editor2.font.size:=Editor1.font.size;
  Editor3.font.size:=Editor1.font.size;
  Editor4.font.size:=Editor1.font.size;
  EditWidth1.font.assign(Editor1.font);
  EditWidth1.font.color:=clblack;
  EditWidth2.font.assign(Editor1.font);
  EditWidth2.font.color:=clblack;
  EditWidth3.font.assign(Editor1.font);
  EditWidth3.font.color:=clblack;
  EditWidth4.font.assign(Editor1.font);
  EditWidth4.font.color:=clblack;
  UpdateFontSize;
end;

procedure TFormEditor.MenuCutClick(Sender: TObject);
begin
  ActiveEditor.CutToClipboard;
end;

procedure TFormEditor.MenuCopyClick(Sender: TObject);
begin
  ActiveEditor.CopyToClipboard;
end;

procedure TFormEditor.MenuPasteClick(Sender: TObject);
begin
  ActiveEditor.PasteFromClipboard;
end;

procedure TFormEditor.MenuFontClick(Sender: TObject);
begin
  DialogFont.font.assign(ActiveEditor.font);
  if DialogFont.execute = false then exit;
  Editor1.font.assign(DialogFont.font);
  Editor2.font.assign(DialogFont.font);
  Editor3.font.assign(DialogFont.font);
  Editor4.font.assign(DialogFont.font);
  EditWidth1.font.assign(Editor1.font);
  EditWidth1.font.color:=clblack;
  EditWidth1.color:=clsilver;
  EditWidth2.font.assign(Editor1.font);
  EditWidth2.font.color:=clblack;
  EditWidth2.color:=clsilver;
  EditWidth3.font.assign(Editor1.font);
  EditWidth3.font.color:=clblack;
  EditWidth3.color:=clsilver;
  EditWidth4.font.assign(Editor1.font);
  EditWidth4.font.color:=clblack;
  EditWidth4.color:=clsilver;
  UpdateFontSize;
end;

procedure TFormEditor.BtnAutotypeMouseMove(Sender: TObject;
  Shift: TShiftState; X, Y: Integer);
begin
  Status.panels[2].text:=(sender as TControl).hint;
end;

procedure TFormEditor.LoadFiles;
begin
  LastFiles.clear;
  LastFiles.add(Datawell.TableOptions.fieldbyname('Last0').asstring);
  LastFiles.add(Datawell.TableOptions.fieldbyname('Last1').asstring);
  LastFiles.add(Datawell.TableOptions.fieldbyname('Last2').asstring);
  LastFiles.add(Datawell.TableOptions.fieldbyname('Last3').asstring);
  LastFiles.add(Datawell.TableOptions.fieldbyname('Last4').asstring);
  LastFiles.add(Datawell.TableOptions.fieldbyname('Last5').asstring);
  LastFiles.add(Datawell.TableOptions.fieldbyname('Last6').asstring);
  LastFiles.add(Datawell.TableOptions.fieldbyname('Last7').asstring);
  LastFiles.add(Datawell.TableOptions.fieldbyname('Last8').asstring);
  LastFiles.add(Datawell.TableOptions.fieldbyname('Last9').asstring);
  UpdateMenu;
end;

procedure TFormEditor.SaveFiles; 
begin
  Datawell.TableOptions.edit;
  Datawell.TableOptions.fieldbyname('Last0').asstring:=LastFiles[0];
  Datawell.TableOptions.fieldbyname('Last1').asstring:=LastFiles[1];
  Datawell.TableOptions.fieldbyname('Last2').asstring:=LastFiles[2];
  Datawell.TableOptions.fieldbyname('Last3').asstring:=LastFiles[3];
  Datawell.TableOptions.fieldbyname('Last4').asstring:=LastFiles[4];
  Datawell.TableOptions.fieldbyname('Last5').asstring:=LastFiles[5];
  Datawell.TableOptions.fieldbyname('Last6').asstring:=LastFiles[6];
  Datawell.TableOptions.fieldbyname('Last7').asstring:=LastFiles[7];
  Datawell.TableOptions.fieldbyname('Last8').asstring:=LastFiles[8];
  Datawell.TableOptions.fieldbyname('Last9').asstring:=LastFiles[9];
  Datawell.TableOptions.post;
  LastFiles.clear;
end;

procedure TFormEditor.MenuClearAllClick(Sender: TObject);
var i: integer;
begin
  LastFiles.clear;
  for i:=0 to 9 do LastFiles.add('');
  UpdateMenu;
end;

procedure TFormEditor.UpdateMenu;
var isone: boolean;
begin
  isone:=false;
  MenuLast0.visible:=false;
  MenuLast1.visible:=false;
  MenuLast2.visible:=false;
  MenuLast3.visible:=false;
  MenuLast4.visible:=false;
  MenuLast5.visible:=false;
  MenuLast6.visible:=false;
  MenuLast7.visible:=false;
  MenuLast8.visible:=false;
  MenuLast9.visible:=false;
  FilterMenu;
  if LastFiles[0] <> '' then begin
    MenuLast0.caption:='&0 '+LastFiles[0]; MenuLast0.visible:=true;
    isone:=true;
  end;
  if LastFiles[1] <> '' then begin
    MenuLast1.caption:='&1 '+LastFiles[1]; MenuLast1.visible:=true;
    isone:=true;
  end;
  if LastFiles[2] <> '' then begin
    MenuLast2.caption:='&2 '+LastFiles[2]; MenuLast2.visible:=true;
    isone:=true;
  end;
  if LastFiles[3] <> '' then begin
    MenuLast3.caption:='&3 '+LastFiles[3]; MenuLast3.visible:=true;
    isone:=true;
  end;
  if LastFiles[4] <> '' then begin
    MenuLast4.caption:='&4 '+LastFiles[4]; MenuLast4.visible:=true;
    isone:=true;
  end;
  if LastFiles[5] <> '' then begin
    MenuLast5.caption:='&5 '+LastFiles[5]; MenuLast5.visible:=true;
    isone:=true;
  end;
  if LastFiles[6] <> '' then begin
    MenuLast6.caption:='&6 '+LastFiles[6]; MenuLast6.visible:=true;
    isone:=true;
  end;
  if LastFiles[7] <> '' then begin
    MenuLast7.caption:='&7 '+LastFiles[7]; MenuLast7.visible:=true;
    isone:=true;
  end;
  if LastFiles[8] <> '' then begin
    MenuLast8.caption:='&8 '+LastFiles[8]; MenuLast8.visible:=true;
    isone:=true;
  end;
  if LastFiles[9] <> '' then begin
    MenuLast9.caption:='&9 '+LastFiles[9]; MenuLast9.visible:=true;
    isone:=true;
  end;
  if isone then begin
    MenuBar.visible:=true;
    MenuClearAll.visible:=true;
    MenuNone.visible:=false;
  end
  else begin
    MenuBar.visible:=false;
    MenuClearAll.visible:=false;
    MenuNone.visible:=true;
  end;
end;

procedure TFormEditor.MenuLast0Click(Sender: TObject);
var
  mr: TModalResult;
  fil: string;
begin
  if BtnSave.enabled then begin
    messagebeep($FFFFFFFF);
    mr:=messagedlg('Save changes to '+DialogSave.filename+'?',
      mtconfirmation,[mbyes,mbno,mbcancel],0);
    if mr = mrcancel then exit;
    if mr = mryes then MenuSaveClick(sender)
  end;
  ActiveEditor.lines.clear;
  fil:=LastFiles[(sender as TMenuItem).tag];
  if not fileexists(fil) then begin
    messagedlg('File does not exist',mtinformation,[mbok],0);
    FilterMenu;
    UpdateMenu;
    exit;
  end;
  try ActiveEditor.lines.loadfromfile(fil);
    except on EFOpenError do begin
      messagedlg('The file is locked by another application',mtinformation,[mbok],0);
      exit;
    end;
  end;
  Status.panels[1].text:='';
  DialogSave.filename:=fil;
  AddFile(fil);
  SetActiveSaved(fil);
  UpdateSaves;
end;

procedure TFormEditor.AddFile(str: string);
begin
  while LastFiles.indexof(str) >= 0 do begin
    LastFiles.delete(LastFiles.indexof(str));
  end;
  LastFiles.insert(0,str);
  UpdateMenu;
end;

procedure TFormEditor.FilterMenu;
var
  i: integer;
  finished: boolean;
begin
  finished:=false;
  while not finished do begin
    finished:=true;
    for i:=0 to LastFiles.count-1 do begin
      if not fileexists(LastFiles[i]) then begin
        LastFiles.delete(i);
        finished:=false;
        break;
      end;
    end;
  end;
  while LastFiles.count < 10 do LastFiles.add('');
end;

procedure TFormEditor.MenuNoteClick(Sender: TObject);
begin
  MenuNewClick(Sender);
  case (sender as TMenuItem).tag of
    0: begin
         ActiveEditor.lines.add('note <Enter Title of Note Here>');
         ActiveEditor.lines.add('<Type Body of Note Here>');
         ActiveEditor.lines.add('**');
         ActiveEditor.lines.add('');
       end;
    1: begin
         ActiveEditor.lines.add('mail <Enter Recipient''s Name Here>');
         ActiveEditor.lines.add('<Enter Subject Here>');
         ActiveEditor.lines.add('<Type Body of Mail Here>');
         ActiveEditor.lines.add('**');
         ActiveEditor.lines.add('');
         ActiveEditor.lines.add('');
       end;
    2: begin
         ActiveEditor.lines.add('mail <Recipient1>, <Recipient2>, <Recipient3>');
         ActiveEditor.lines.add('<Enter Subject Here>');
         ActiveEditor.lines.add('<Type Body of Mail Here>');
         ActiveEditor.lines.add('**');
         ActiveEditor.lines.add('');
         ActiveEditor.lines.add('');
       end;
  end;
  SetActiveSaved('untitled');
end;

procedure TFormEditor.MenuFindClick(Sender: TObject);
begin
  if not Datawell.CheckRinged(false,'Autotyper search') then exit;
  DialogReplace.execute;
end;

procedure TFormEditor.MenuFindNextClick(Sender: TObject);
begin
  if not Datawell.CheckRinged(false,'Autotyper search') then exit;
  if DialogReplace.FindText = '' then exit;
  if not DoSearch then
    messagedlg('"'+DialogReplace.FindText+'" not found',mtinformation,[mbok],0);
end;

procedure TFormEditor.DialogReplaceReplace(Sender: TObject);
var doingall: boolean;
begin
  doingall:=false;
  PrepareSearch(DialogReplace);
  with DialogReplace do begin
    RStr:=StrAlloc(length(ReplaceText)+1);
    StrPCopy(RStr,ReplaceText);
    if frReplaceAll in Options then begin
      doingall:=true;
      while DoSearch do DoReplace;
    end
    else begin
      if not DoSearch then
        messagedlg('"'+DialogReplace.FindText+'" not found',mtinformation,[mbok],0)
      else DoReplace;
    end;
    StrDispose(RStr);
  end;
  if doingall then DialogReplace.CloseDialog;
end;

procedure TFormEditor.DialogReplaceFind(Sender: TObject);
begin
  DialogReplace.CloseDialog;
  PrepareSearch(DialogReplace);
  if not DoSearch then begin
    messagedlg('"'+DialogReplace.FindText+'" not found',mtinformation,[mbok],0);
  end
  else ActiveEditor.perform(EM_SCROLLCARET,0,0);
end;

procedure TFormEditor.MenuShowWidthbarClick(Sender: TObject);
begin
  TMenuItem(sender).checked:=not TMenuItem(sender).checked;
  case TMenuItem(sender).tag of
    0: begin
         if MenuShowWidthbar.checked then PanelWidth1.height:=16
         else PanelWidth1.height:=0;
         PanelWidth2.height:=PanelWidth1.height;
         PanelWidth3.height:=PanelWidth1.height;
         PanelWidth4.height:=PanelWidth1.height;
       end;
    3: begin
         UpdateSaves;
       end;
    4: begin
         Editor1.wordwrap:=TMenuItem(sender).checked;
         Editor2.wordwrap:=TMenuItem(sender).checked;
         Editor3.wordwrap:=TMenuItem(sender).checked;
         Editor4.wordwrap:=TMenuItem(sender).checked;
         if Editor1.wordwrap then Editor1.scrollbars:=ssvertical else
            Editor1.scrollbars:=ssboth;
         Editor2.scrollbars:=Editor1.scrollbars;
         Editor3.scrollbars:=Editor1.scrollbars;
         Editor4.scrollbars:=Editor1.scrollbars;
       end;
  end;
end;

procedure TFormEditor.MenuUndoClick(Sender: TObject);
begin
  with ActiveEditor do begin
    if HandleAllocated then SendMessage(Handle,EM_UNDO,0,0);
  end;
end;

procedure TFormEditor.BtnHelpClick(Sender: TObject);
begin
  Datawell.Help('autotyper');
end;

procedure TFormEditor.UpdateCursorPos;
var i, amt: integer;
begin
  i:=ActiveEditor.Perform(em_LineFromChar,-1,0)+1;
  amt:=ActiveEditor.lines.count;
  if amt < 1 then amt:=1;
  if i > amt then amt:=i;
  Status.panels[0].text:='Line: '+inttostr(i)+' / '+inttostr(amt);
end;

procedure TFormEditor.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  UpdateCursorPos;
end;

procedure TFormEditor.Editor1MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  UpdateCursorPos;
end;

procedure TFormEditor.UpdateFontSize;
begin
  LabelFont.caption:=inttostr(ActiveEditor.font.size);
end;

procedure TFormEditor.MenuDeleteLineClick(Sender: TObject);
var i, charscounted: integer;
begin
  if (ActiveEditor.selstart = 0) and (ActiveEditor.lines.count > 0) then begin
    ActiveEditor.lines.delete(0);
    exit;
  end;
  i:=0;
  charscounted:=0;
  while (charscounted <= ActiveEditor.selstart) and (i < ActiveEditor.lines.count) do begin
    inc(charscounted,length(ActiveEditor.lines[i]));
    inc(charscounted,2);
    inc(i);
  end;
  ActiveEditor.lines.delete(i-1);
  UpdateCursorPos;
end;

procedure TFormEditor.EditWidth1Click(Sender: TObject);
begin
  ActiveEditor.setfocus;
end;

procedure TFormEditor.EscapeClick(Sender: TObject);
begin
  FormMain.show;
  with Datawell.TableOptions do begin
    edit;
    fieldbyname('EditorTop').asinteger:=top;
    fieldbyname('EditorLeft').asinteger:=left;
    fieldbyname('EditorHeight').asinteger:=height;
    fieldbyname('EditorWidth').asinteger:=width;
    fieldbyname('EditorFontName').asstring:=Editor1.font.name;
    if Editor1.font.style = [fsbold] then Datawell.TableOptions.fieldbyname('EditorFontStyle').asinteger:=1
    else if Editor1.font.style = [fsitalic] then Datawell.TableOptions.fieldbyname('EditorFontStyle').asinteger:=2
    else if Editor1.font.style = [fsbold, fsitalic] then Datawell.TableOptions.fieldbyname('EditorFontStyle').asinteger:=3
    else Datawell.TableOptions.fieldbyname('EditorFontStyle').asinteger:=0;
    fieldbyname('EditorFontSize').asinteger:=Editor1.font.size;
    fieldbyname('EditorFColor').asinteger:=Editor1.font.color;
    fieldbyname('EditorBColor').asinteger:=Editor1.color;
    fieldbyname('EditorWrap').asboolean:=MenuEnableWordWrap.checked;
    fieldbyname('AutotypeSave').asboolean:=MenuSaveAlert.checked;
    fieldbyname('EditorClear').asboolean:=MenuClearOnAutotype.checked;
    fieldbyname('EditorAsk').asboolean:=MenuAskOnEmpty.checked;
    fieldbyname('EditorShowWidthbar').asboolean:=MenuShowWidthBar.checked;
    fieldbyname('EditorStayOnTop').asboolean:=MenuStayOnTop.checked;
    post;
  end;
end;

procedure TFormEditor.MenuDeleteAllClick(Sender: TObject);
begin
  ActiveEditor.lines.clear;
  Editor1Change(Sender);
end;

procedure TFormEditor.MenuCtrlTabClick(Sender: TObject);
begin
  if TMenuItem(sender).tag = 0 then FormMain.NextScreen(1)
  else FormMain.PriorScreen(1);
end;

procedure TFormEditor.MenuChatClick(Sender: TObject);
begin
  FormMain.OpenFloater(TComponent(sender).tag);
end;

procedure TFormEditor.MenuPanicClick(Sender: TObject);
begin
  FormMain.MenuPanic.click;
end;

procedure TFormEditor.MenuStayOnTopClick(Sender: TObject);
begin
  TMenuItem(sender).checked:=not TMenuItem(sender).checked;
  if MenuStayOnTop.checked = true then formstyle:=fsstayontop
  else formstyle:=fsnormal;
end;

procedure TFormEditor.MenuChooseColorsClick(Sender: TObject);
var
  form: TFormColor;
  fi, bi: integer;
begin
  form:=TFormColor.create(self);
  form.ColorGrid.foregroundindex:=Datawell.ColorFigure(Editor1.font.color);
  form.ColorGrid.backgroundindex:=Datawell.ColorFigure(Editor1.color);
  form.showmodal;
  fi:=form.findex;
  bi:=form.bindex;
  form.free;
  if (fi < 0) or (bi < 0) then exit;
  Editor1.font.color:=Datawell.FigureColor(fi);
  Editor2.font.color:=Editor1.font.color;
  Editor3.font.color:=Editor1.font.color;
  Editor4.font.color:=Editor1.font.color;
  Editor1.color:=Datawell.FigureColor(bi);
  Editor2.color:=Editor1.color;
  Editor3.color:=Editor1.color;
  Editor4.color:=Editor1.color;
end;

procedure TFormEditor.TabsChange(Sender: TObject);
begin
  UpdateCursorPos;
  UpdateSaves;
  UpdateCaption;
  CheckContent;
  if (visible) and (active) then ActiveEditor.setfocus;
end;

procedure TFormEditor.UpdateSaves;
begin
  BtnSave.enabled:=true;
  if ((Tabs.activepage = Tab1) and (not m1)) or
     ((Tabs.activepage = Tab2) and (not m2)) or
     ((Tabs.activepage = Tab3) and (not m3)) or
     ((Tabs.activepage = Tab4) and (not m4)) then begin
    Status.panels[1].text:='';
    BtnSave.enabled:=false;
  end;
  BtnSaveAll.enabled:=true;
  if (not m1) and (not m2) and (not m3) and (not m4) then BtnSaveAll.enabled:=false;
  if BtnSave.enabled then Status.panels[1].text:='Modified'
  else Status.panels[1].text:='';
end;

procedure TFormEditor.MenuFile1Click(Sender: TObject);
begin
  case TComponent(sender).tag of
    1: if Tabs.activepage <> Tab1 then Tabs.activepage:=Tab1;
    2: if Tabs.activepage <> Tab2 then Tabs.activepage:=Tab2;
    3: if Tabs.activepage <> Tab3 then Tabs.activepage:=Tab3;
    4: if Tabs.activepage <> Tab4 then Tabs.activepage:=Tab4;
  end;
  TabsChange(sender);
end;

procedure TFormEditor.FocusFile(which: integer);
begin
  case which of
    1: if Tabs.activepage <> Tab1 then Tabs.activepage:=Tab1;
    2: if Tabs.activepage <> Tab2 then Tabs.activepage:=Tab2;
    3: if Tabs.activepage <> Tab3 then Tabs.activepage:=Tab3;
    4: if Tabs.activepage <> Tab4 then Tabs.activepage:=Tab4;
  end;
  TabsChange(nil);
end;

procedure TFormEditor.FormDestroy(Sender: TObject);
begin
  LastFiles.free;
end;

procedure TFormEditor.BtnSpellCheckClick(Sender: TObject);
begin
{  if not Datawell.CheckRinged(false,'Autotyper spellcheck/thesaurus') then exit;
  case TSpeedButton(sender).tag of
    1: Spell.CheckWinControl(ActiveEditor,ctAll);
    2: Thesaurus.LookupWinControl(ActiveEditor);
  end;}
end;

procedure TFormEditor.MenuDownloadClick(Sender: TObject);
begin
  MenuNewClick(sender);
  ActiveEditor.lines.assign(FormMain.Download);
  ActiveEditor.sellength:=0;
  ActiveEditor.selstart:=0;
end;

end.
